package org.yelongframework.spring.web.servlet;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**
 * 默认实现
 * 
 * @since 1.0.0
 */
public class DefaultSpringWebMvcSupport implements SpringWebMvcSupport, ApplicationContextAware {

	/** 应用上下文 */
	private ApplicationContext applicationContext;

	// ==================================================处理器方法==================================================

	@Override
	public HandlerMethod getRequestMappingHandlerMethod(HttpServletRequest request) throws Exception {
		RequestMappingHandlerMapping requestMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
		HandlerExecutionChain handler = requestMapping.getHandler(request);
		return (HandlerMethod) handler.getHandler();
	}

	@Override
	public HandlerMethod getCurrentRequestMappingHandlerMethod() throws Exception {
		return getRequestMappingHandlerMethod(getRequest());
	}

	// ==================================================请求==================================================

	@Override
	public HttpServletRequest getRequest() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	}

	// ==================================================响应==================================================

	@Override
	public HttpServletResponse getResponse() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
	}

	// ==================================================注册控制器==================================================

	@Override
	public void registryController(String beanName, Class<?> beanClass) throws Exception {
		DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext
				.getAutowireCapableBeanFactory();
		BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(beanClass);
		defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
		RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext
				.getBean(RequestMappingHandlerMapping.class);
		Method method = requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass()
				.getDeclaredMethod("detectHandlerMethods", Object.class);
		method.setAccessible(true);
		method.invoke(requestMappingHandlerMapping, beanName);
	}

	// ==================================================应用上下文==================================================

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

}
